package com.coastwe.lambda;

import java.util.function.*;

public class HelloWorld {

    public static void main(String[] args) {
        define();

        functionInterface();

        typeInference();

        methodReference();

        composite();
    }

    public static void define() {
        // (paramters) -> expression
        Function<String, Integer> function1 = (String s) -> s.length();

        System.out.println(function1.apply("hello"));
        // (paramters) -> {statements;}
        Function<String, Integer> function2 = (String s) -> {
            return s.length();
        };
        System.out.println(function2.apply("hello"));
    }

    public static void functionInterface() {
        //test  (T) -> Boolean
        Predicate<String> predicate = (String s) -> s != null;
        System.out.println(predicate.test(null));
        System.out.println(predicate.test("hello"));
        //原始类型
        IntPredicate intPredicate = (int i) -> i<5;
        System.out.println(intPredicate.test(5));

        //(T,R) -> Boolean
        BiPredicate<String, Integer> biPredicate = (String s, Integer i) -> s.length() > i;
        System.out.println(biPredicate.test("hello", 5));

        //(T) -> void
        Consumer<String> consumer = (String s) -> System.out.println(s);
        consumer.accept("hello consumer");

        //(T) -> R
        Function<String, Integer> function = (String s) -> s.length();
        System.out.println(function.apply("hello"));

        // (void) -> T
        Supplier<String> supplier = () -> new String("hello supplier");
        System.out.println(supplier.get());

        // (T) -> T
        UnaryOperator<String> unaryOperator = (String s) -> s.concat(",unaryOperator");
        System.out.println(unaryOperator.apply("hello"));

        //(T,T) -> T
        BinaryOperator<String> binaryOperator = (String s1, String s2) -> s1.concat(s2);
        System.out.println(binaryOperator.apply("hello,","binaryOperator"));

    }

    /**
     * 类型推断
     */
    public static void typeInference() {
        Function<String, Integer> function1 = (s) -> s.length();
        System.out.println(function1.apply("hello"));
    }

    /**
     * 方法引用
     */
    public static void methodReference() {
        //指向静态方法的方法引用
        Function<String, Integer> function = Integer::parseInt;
        Function<String, Integer> function1 = (s) -> Integer.parseInt(s);
        System.out.println("静态方法的方法引用");
        System.out.println(function.apply("5"));
        System.out.println(function1.apply("5"));
        System.out.println("静态方法的方法引用");

        //指向任意类型的实例方法的方法引用
        Function<String, Integer> function2 = (String s) -> s.length();
        Function<String, Integer> function3 = String::length;
        System.out.println("指向任意类型的实例方法的方法引用");
        System.out.println(function2.apply("hello"));
        System.out.println(function3.apply("hello"));
        System.out.println("指向任意类型的实例方法的方法引用");

        //指向现有对象的实例方法的方法引用
        Consumer<String> consumer = (s) -> System.out.println(s);
        Consumer<String> consumer1 = System.out::println;
        System.out.println("指向现有对象的实例方法的方法引用");
        consumer.accept("指向现有对象的实例方法的方法引用");
        consumer1.accept("指向现有对象的实例方法的方法引用");
        System.out.println("指向现有对象的实例方法的方法引用");

        //构造函数方法引用
        Supplier<String> supplier = String::new;
        UnaryOperator<String> unaryOperator = String::new;
        System.out.println(supplier.get());
        System.out.println(unaryOperator.apply("hello"));

    }

    /**
     * 比较器复合
     */
    public static void composite() {
        //谓词复合
        Predicate<Integer> predicate = (i) -> i > 10;
        Predicate<Integer> predicate1 = predicate.and((i) -> i < 100);
        Predicate<Integer> predicate2 = predicate1.or((i) -> i > 500);
        System.out.println(predicate.negate().test(10));
        System.out.println(predicate1.test(100));
        System.out.println(predicate1.test(58));
        System.out.println(predicate2.test(501));
        System.out.println(predicate2.test(90));
        System.out.println(predicate2.test(120));

        //函数复合
    }
}
